Skip to content

Docker Containerization with CI/CD Pipeline#3

Closed
bakerboy448 wants to merge 7 commits intomainfrom
feature/docker-bot
Closed

Docker Containerization with CI/CD Pipeline#3
bakerboy448 wants to merge 7 commits intomainfrom
feature/docker-bot

Conversation

@bakerboy448
Copy link
Collaborator

Summary

  • Add complete Docker containerization with multi-platform builds
  • GitHub Actions CI/CD pipeline for ghcr.io and Docker Hub
  • Pre-commit hooks for code quality and security validation
  • Comprehensive Docker deployment documentation

Docker Features

  • Multi-stage Dockerfile: Python 3.11-slim base with non-root user security
  • Health checks: SQLite connectivity validation
  • Volume mounts: Persistent data and logs storage
  • Environment variables: Full configuration support
  • Resource limits: Memory and CPU constraints

CI/CD Pipeline

  • Multi-platform builds: linux/amd64 and linux/arm64
  • Dual registry support: GitHub Container Registry (ghcr.io) and Docker Hub
  • Manual approval: Required for main branch deployments
  • Automatic metadata: Semantic versioning tags and labels
  • Cache optimization: GitHub Actions cache for faster builds

Pre-commit Hooks

  • Code quality: Black, flake8, isort, mypy
  • Security: detect-secrets for credential scanning
  • Validation: YAML, file size, merge conflicts
  • Custom checks: Reddit config safety validation

Test plan

  • Build Docker image locally
  • Test docker-compose deployment
  • Verify environment variable configuration
  • Test health checks and volume mounts
  • Validate pre-commit hooks installation
  • Test GitHub Actions workflow (after merge)
  • Verify multi-platform builds
  • Test registry pushes to ghcr.io and Docker Hub

🤖 Generated with Claude Code

Copilot AI review requested due to automatic review settings August 18, 2025 04:18
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds comprehensive Docker containerization with CI/CD pipeline support to the Reddit modlog bot project, enabling production deployment with automated builds and deployment workflows.

  • Adds Docker containerization with multi-stage builds, health checks, and security-focused non-root user configuration
  • Implements GitHub Actions CI/CD pipeline for automated multi-platform builds to GitHub Container Registry and Docker Hub
  • Introduces pre-commit hooks for code quality validation including security scanning and formatting checks

Reviewed Changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
docker-compose.yml Production-ready Docker Compose configuration with environment variables, health checks, and resource limits
Dockerfile Multi-stage Docker build with Python 3.11-slim, non-root user security, and health check implementation
CLAUDE.md Updated documentation with Docker deployment instructions and CI/CD workflow details
.pre-commit-config.yaml Pre-commit hooks configuration for code quality, security scanning, and Reddit config validation
.github/workflows/docker-build.yml GitHub Actions workflow for automated Docker builds with multi-platform support and dual registry deployment
.dockerignore Docker build context exclusions for sensitive files, logs, and development artifacts

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.


# Health check
healthcheck:
test: ["CMD", "python", "-c", "import sqlite3; conn = sqlite3.connect('/app/data/modlog.db'); conn.close()"]
Copy link

Copilot AI Aug 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The health check hardcodes the database path instead of using the DB_PATH environment variable defined in the Dockerfile. This creates inconsistency between the two files and makes the configuration less maintainable.

Suggested change
test: ["CMD", "python", "-c", "import sqlite3; conn = sqlite3.connect('/app/data/modlog.db'); conn.close()"]
test: ["CMD-SHELL", "python -c \"import os, sqlite3; conn = sqlite3.connect(os.environ['DB_PATH']); conn.close()\""]

Copilot uses AI. Check for mistakes.
Dockerfile Outdated

# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD python -c "import sqlite3; conn = sqlite3.connect('${DB_PATH}'); conn.close()" || exit 1
Copy link

Copilot AI Aug 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The HEALTHCHECK command uses shell variable expansion (${DB_PATH}) but runs in exec form, which doesn't perform shell expansion. This will cause the health check to fail as it will literally look for a file named '${DB_PATH}' instead of the actual path.

Suggested change
CMD python -c "import sqlite3; conn = sqlite3.connect('${DB_PATH}'); conn.close()" || exit 1
CMD python -c "import sqlite3; conn = sqlite3.connect(\"${DB_PATH}\"); conn.close()" || exit 1

Copilot uses AI. Check for mistakes.
hooks:
- id: reddit-config-check
name: Check Reddit config safety
entry: python -c "import json; config = json.load(open('config.json')) if __import__('os').path.exists('config.json') else {}; exit(1) if not config.get('anonymize_moderators', True) else exit(0)"
Copy link

Copilot AI Aug 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Reddit config check is implemented as a complex one-liner that's difficult to read and maintain. Consider extracting this to a separate script file for better readability and testability.

Copilot uses AI. Check for mistakes.
uses: docker/setup-buildx-action@v3

- name: Login to GitHub Container Registry
if: github.event_name != 'pull_request' && (github.ref_type == 'tag' || inputs.deploy_to_main == true)
Copy link

Copilot AI Aug 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The workflow allows manual deployment to production registries without proper authorization checks. Consider adding an environment protection rule or additional approval step for production deployments to prevent unauthorized releases.

Suggested change
if: github.event_name != 'pull_request' && (github.ref_type == 'tag' || inputs.deploy_to_main == true)
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: |
${{ env.REGISTRY_GHCR }}/${{ env.IMAGE_NAME }}
${{ env.REGISTRY_DOCKERHUB }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=raw,value=latest,enable={{is_default_branch}}
- name: Build (no push)
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64
push: false
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
deploy-production:
if: github.event_name != 'pull_request' && (github.ref_type == 'tag' || inputs.deploy_to_main == true)
runs-on: ubuntu-latest
environment: production
permissions:
contents: read
packages: write
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GitHub Container Registry

Copilot uses AI. Check for mistakes.
@bakerboy448 bakerboy448 force-pushed the feature/docker-bot branch 2 times, most recently from 6b6b411 to a5ee2fd Compare September 7, 2025 16:07
@bakerboy448 bakerboy448 force-pushed the feature/docker-bot branch 2 times, most recently from 22ece8c to 5b32ecc Compare October 18, 2025 08:35
Features:
- Complete Docker containerization with s6-overlay init
- PUID/PGID support for proper file permissions
- Multi-architecture builds (amd64/arm64)
- GitHub Actions CI/CD pipeline for ghcr.io publishing
- OpenContainer labels for proper metadata

Systemd improvements:
- Template-based service for multiple subreddits
- Per-subreddit config files in /etc/redditmodlog/
- Centralized logging to /var/log/redditmodlog/
- Automatic log rotation (30 days, 100MB max)
- Security hardening with read-only filesystem
- Resource limits (256MB RAM, 25% CPU)

Infrastructure:
- Installation script for easy deployment
- Logrotate configuration included
- Enhanced .gitignore for sensitive files
- Updated README with Docker and systemd documentation

This provides production-ready deployment options for both Docker and systemd environments.
- Change data directory from /app to /config for consistency
- Add startup validation for critical environment variables
- Fix GitHub Actions workflow image name to lowercase (GHCR requirement)
- Fix health check to use DATABASE_PATH env var
- Update all volume mounts to use /config instead of /app
- Add proper exit on missing required env vars:
  - REDDIT_CLIENT_ID
  - REDDIT_CLIENT_SECRET
  - REDDIT_USERNAME
  - REDDIT_PASSWORD
  - SOURCE_SUBREDDIT
- Simplify GitHub Actions tag pattern (remove invalid branch prefix)
- Update README documentation for /config paths
Critical fixes from expert review:
- Fix multi-arch builds: s6-overlay now selects correct architecture
  (x86_64 for amd64, aarch64 for arm64, arm for arm/v7)
- Fix GitHub Actions SBOM generation image reference
- Fix GitHub Actions Trivy security scan image reference
- Fix resource limits: use Compose v2 syntax instead of swarm-only deploy
- Remove obsolete version directive from docker-compose.yml
- Remove unnecessary reverse proxy network comments
- Document unsupported env vars (MAX_WIKI_ENTRIES_PER_PAGE, MAX_CONTINUOUS_ERRORS)

This resolves blocking issues for arm64 builds and CI/CD pipeline.
Restore .pre-commit-config.yaml that was in original PR but missing from
current branch. This file provides code quality, security scanning, and
formatting validation hooks.
Add .editorconfig to maintain consistent formatting across editors:
- Python: 4 spaces, max line 88 (matches black)
- YAML/JSON: 2 spaces
- Unix line endings (LF)
- UTF-8 encoding
- Trim trailing whitespace
- Black reformatted with --line-length=180
- Fixed trailing whitespace and EOF issues
- Fixed Dockerfile FROM casing (AS instead of as)
@bakerboy448 bakerboy448 deleted the feature/docker-bot branch October 30, 2025 23:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants